home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / sml_nj / 93src.lha / src / modules / instantiate.sml < prev    next >
Encoding:
Text File  |  1993-02-11  |  47.2 KB  |  1,262 lines

  1. (* Copyright 1991 by AT&T Bell Laboratories *)
  2. (* instantiate.sml *)
  3.  
  4. (* This function constructs a dummy structure which satisfies all sharing
  5.  * constraints (explicit or induced) of a given signature.  The resulting
  6.  * structure is used as the dummy parameter of a functor while parsing,
  7.  * type-checking, and abstracting the functor body.
  8.  *
  9.  * The process of constructing the structure is essentially a unification
  10.  * problem.  The algorithm used here is based on the Linear Unification
  11.  * algorithm first presented in [1] which was subsequently corrected
  12.  * and cleaned up in [2].
  13.  *
  14.  * This code was originally designed by Damien Doligez, Georgez Gothier, 
  15.  * and Dave MacQueen.  Greg Morrisett, Dave MacQueen, and David Tarditi
  16.  * modified the code to work with the current implementation of the
  17.  * SML/NJ module system.
  18.  *
  19.  * The basic algorithm makes 2 passes.  The first pass builds a DAG in
  20.  * a quasi-top down fashion which corresponds to the minimal structure 
  21.  * needed to match the signature.  The second pass takes the DAG and
  22.  * constructs the actualy dummy structure in a bottom-up fashion.
  23.  * Pass 1 has a fairly complicated control structure.  The major 
  24.  * invariant is that no node in the graph is expanded unless all 
  25.  * of its ancestors have been expanded.  This insures that all sharing
  26.  * constraints (explicit or implicit) have reached the node at the
  27.  * time of its expansion.  The second major invariant is that no
  28.  * node is finalized until all members in its equivalence class have
  29.  * been found.
  30.  *
  31.  * [1] Paterson, M.S., and Wegman, M.N., "Linear Unification", 
  32.  *     J. Comp. Sys. Sci. 16,2 (April 1978), pp. 158-167.
  33.  *
  34.  * [2] de Champeaux, D., "About the Paterson-Wegman Linear Unification
  35.  *     Algorithm", J. of Comp. Sys. Sci. 32, 1986, pp. 79-88.
  36.  *)
  37.  
  38. structure Instantiate :
  39.     sig
  40.     val instantiate : 
  41.         Modules.Signature * Modules.spath * Stamps.scope * ErrorMsg.complainer
  42.         -> Modules.Structure
  43.     val instantiate_argument : 
  44.         Symbol.symbol
  45.         -> Modules.spath * Stamps.scope * ErrorMsg.complainer
  46.             -> Modules.Structure -> Modules.Signature
  47.             -> Modules.Structure
  48.     end (* sig *) 
  49.  
  50. = struct
  51. open Symbol Modules Types ModuleUtil ErrorMsg TypesUtil
  52.      System.Control Access Stamps PrintUtil Extern
  53.  
  54. open Array List
  55. infix 9 sub
  56.  
  57. val say = System.Print.say
  58.  
  59. val DEBUG = false
  60. fun tprint (s:string) = if DEBUG andalso !internals 
  61.                 then (say s) else ()
  62. fun tprintSym (s:Symbol.symbol) = 
  63.     if DEBUG andalso !internals then (printSym s) else ()
  64. val error_found = ref false
  65.  
  66. (* This datatype represents the continually changing DAG that is being 
  67.  * constructed by instantiate.  We start off with just an Initial node.  
  68.  * It is expanded into a Partial node whose children (subs and typs) are 
  69.  * initialized to Initial nodes.  When all of the members of the nodes
  70.  * equivalence class have been found, and converted to Partial nodes, 
  71.  * the node is converted to either Final_top or Final_embed depending 
  72.  * on its signature kind.  Finally, we recurse on the children of the
  73.  * node.  
  74.  *
  75.  * Invariants:
  76.  *
  77.  *    The parent node is in a singleton equivalence class.
  78.  *
  79.  *    All nodes that are about to be explored are either Initial or Partial.
  80.  *    (Exploring a Final node implies circularity.)
  81.  *
  82.  *    If a Final node's expanded field is true, then all of its children
  83.  *    are Final with expanded field true.
  84.  *
  85.  *    The node (subs sub i) of a structure corresponds to the sub-structure
  86.  *    (actual_subStrs sub i) to be built.  Similarly for (typs sub i) and 
  87.  *    (actual_types sub i)
  88.  *)
  89. datatype instance = Final_top of { sign : Signature,
  90.                    actual_subStrs : Structure array,
  91.                    actual_types : Types.tycon array,
  92.                    origin_info : instance_origin ref,
  93.                                    subs : instance array,
  94.                                    typs : type_ins array,
  95.                    final_struct: Structure option ref,
  96.                    expanded : bool ref}
  97.                   | Final_embed of { sign : Signature,
  98.                                      path : Symbol.symbol list,
  99.                                      origin_info : instance_origin ref,
  100.                                      subs : instance array,
  101.                                      typs : type_ins array,
  102.                      expanded : bool ref}
  103.                   | Partial of { signat : Signature,
  104.                                  path : Symbol.symbol list,
  105.                                  subs : instance array,
  106.                                  typs : type_ins array,
  107.                                  depth : int,
  108.                  final_rep : instance option ref}
  109.                   | Initial of { signat : Signature,
  110.                                  path : Symbol.symbol list,
  111.                                  parent_typs : type_ins array,
  112.                                  inherited : constraint list ref }
  113.                   | NULLinstance
  114.                   | ERRORinstance
  115.  
  116. (* These are the similar nodes for types. *)
  117. and type_ins = tFinal of tycon
  118.              | tPartial of { tycon : tycon,
  119.                              path : Symbol.symbol list }
  120.              | tInitial of { tycon : tycon,
  121.                              path : Symbol.symbol list,
  122.                              inherited : constraint list ref }
  123.              | tNULLinstance
  124.              | tERRORinstance
  125.  
  126. (* Some of the nodes of the structure are not actually constructed
  127.  * since they were previously defined structures or types.  These
  128.  * are labelled with EXTstr and EXTtyc respectively.  The pointers
  129.  * to the nodes of the DAG are destructively updated, 
  130.  * so they are represented using "slots" of an array.
  131.  *)
  132. and instrep = EXTstr of Structure
  133.             | EXTtyc of tycon
  134.             | SLOTstr of instance slot
  135.             | SLOTtyc of type_ins slot
  136.  
  137. (* In the final versions of instances, we need to be able to build an
  138.  * origin structure which has the "union" of all components of structures
  139.  * which it is equivalent too.  If a Final_top or Final_embed instance
  140.  * has origin_info set to BUILT, then the origin field of the structure
  141.  * field points to the origin structure.  If the origin_info is set to
  142.  * NEED_SIMPLE (env), then a SIMPLE origin structure must be constructed 
  143.  * from the instrep env to be shared among all members of an equivalence
  144.  * class of structures as their origin.  If the origin_info is set to 
  145.  * NEED_SELF then the structure is in a singleton equivalence
  146.  * class and we may use the structure as its own origin.  
  147.  *)
  148. and instance_origin = 
  149.     BUILT of Structure | 
  150.     NEED_SELF |
  151.     NEED_SIMPLE of (instrep Env.env)
  152.  
  153. (* A constraint is essentially a directed arc indicating that two
  154.  * nodes are to be identified.  The constraint is always interpreted
  155.  * relative to an instance node.  The my_path field is a symbolic
  156.  * path indicating which subcomponent of the instance is participating
  157.  * in the sharing.  The other component is accessed by first finding
  158.  * the instance node in the its_ancestor slot, and then following
  159.  * the symbolic path its_path to the node.  By going through the
  160.  * ancestor, we are able to insure that the ancestor is explored
  161.  * before the actual component is.
  162.  *)
  163. withtype constraint = { my_path : Symbol.symbol list,
  164.                 its_ancestor : instrep,
  165.             its_path : Symbol.symbol list}
  166.  
  167. and 'a slot = { base : 'a array, offset : int }
  168. fun get {base, offset} = base sub offset
  169. fun set ({base, offset}, inst) = update (base, offset, inst)
  170. fun push r x = (r := x::(!r))
  171.  
  172. (*********************)
  173. (* Utility Functions *)
  174. (*********************)        
  175. (* Retrieves all [formal] substructure components from a signature *)
  176. fun getSubSigs (sign: Modules.Signature) : 
  177.     (Symbol.symbol * Modules.strpos * Modules.Signature) list =
  178.    case sign 
  179.    of SIG {symbols,env,...} =>
  180.     let fun check_binding (s, prevSubSigs) =
  181.       case (nameSpace s)
  182.       of STRspace => 
  183.                ((case Env.look (!env,s)
  184.          of STRbind (STRvar {binding=STR_FORMAL {pos,spec,...},...}) =>
  185.               (s,pos,spec) :: prevSubSigs
  186.           | _ => impossible "Modules.instantiate:getSubSigs 1")
  187.                  handle Env.Unbound => impossible "Modules.getSubSigs 2")
  188.        | _ => prevSubSigs
  189.     in fold check_binding (!symbols) [] end
  190.     | _ => []
  191.  
  192. (* Retrieves all [formal] type components from a signature *)
  193. fun getTypes (sign: Modules.Signature) : 
  194.     (Symbol.symbol * Modules.strpos * Types.tycon) list =
  195.     case sign of
  196.     SIG {symbols,env,...} =>
  197.     let fun check_binding (s, prevTypes) =
  198.         case (nameSpace s) of
  199.         TYCspace => ((case Env.look(!env,s) of
  200.                  TYCbind (tyc as (FORMtyc {pos,spec,...})) =>
  201.                       (s,pos,tyc) :: prevTypes
  202.                    | _ => impossible 
  203.                      "Modules.instantiate:getTypes 2")
  204.                  handle Env.Unbound => 
  205.                  impossible "Modules.instantiate:getTypes 2")
  206.           | _ => prevTypes
  207.     in
  208.         fold check_binding (!symbols) []
  209.     end
  210.       | _ => []
  211.  
  212.  
  213. (* pathName assumes symbol list is in reverse order *)
  214. fun pathName [sym] = Symbol.name sym
  215.   | pathName (sym::rest) = (pathName rest)^"."^(Symbol.name sym)
  216.   | pathName [] = "?"
  217.  
  218. fun strName (SIMPLE {path,...}) = pathName path
  219.   | strName (INSTANCE {path,...}) = pathName path
  220.   | strName _ = "?"
  221.  
  222.  
  223. (* gets all the substructures of a structure *)
  224. fun getSubStrs str =
  225.   let val r = ref nil
  226.   in
  227.   case str
  228.   of (SIMPLE{env,...}) =>
  229.        Env.app 
  230.      (fn (sym,STRbind(STRvar{binding=str,...})) => r := (sym,str) :: !r
  231.        | _ => ())
  232.      env
  233.    | (str as INSTANCE{sign=SIG{env,...},subStrs,...}) =>
  234.        Env.app
  235.      (fn (sym,STRbind(STRvar{binding=STR_FORMAL{pos,...},...})) =>
  236.         r := (sym,Array.sub(subStrs,pos)) :: !r
  237.        | (sym,STRbind(STRvar{binding=STR_OPEN{pos,...},...})) =>
  238.         r := (sym,transPosStr str pos ) :: !r
  239.        | _ => ())
  240.      (!env)
  241.    | (INSTANCE{sign=ERROR_SIG,...}) => ()
  242.    | APPLY{res,...} => r:=getSubStrs res
  243.    | ERROR_STR => ()
  244.    | _ => impossible "getSubStrs";
  245.   !r
  246.   end
  247.  
  248. (* Creates instrep nodes for all of the substructures of a
  249.  * presumably pre-defined (i.e. external) structure.
  250.  *)
  251. fun getStrSlots (str : Structure) : (symbol * instrep) list =
  252.     let fun f (sym, str) = (sym, EXTstr (getOrigin str))
  253.     in map f (getSubStrs str)
  254.     end
  255.  
  256. fun getSubTyps str =
  257.   let val r = ref nil
  258.   in
  259.   case str
  260.   of (SIMPLE{env,...}) =>
  261.        Env.app 
  262.      (fn (sym,TYCbind tyc) => r := (sym,tyc) :: !r
  263.        | _ => ())
  264.      env
  265.    | (str as INSTANCE{sign=SIG{env,...},types,...}) =>
  266.        Env.app
  267.      (fn (sym,TYCbind (OPENFORMtyc{pos=(path,pos),...})) => 
  268.         r := (sym,transPosTycon str (path @ [pos])) :: !r
  269.         | (sym,TYCbind (FORMtyc{pos,...})) => 
  270.         r := (sym,Array.sub(types,pos)) :: !r
  271.         | _ => ()) 
  272.      (!env)
  273.    | (INSTANCE{sign=ERROR_SIG,...}) => (error_found := true; ())
  274.    | APPLY{res,...} => r:=getSubTyps res
  275.    | ERROR_STR => (error_found := true; ())
  276.    | _ => impossible "Instantiate:getSubTyps";
  277.   !r
  278.   end
  279.            
  280.         
  281. fun getStrTSlots (str : Structure) : (symbol * instrep) list =
  282.     let fun f (sym, tyc) = (sym, EXTtyc tyc)
  283.     in map f (getSubTyps str)
  284.     end
  285.  
  286. (* Finds all sub-signatures in a signature, and updates the corresponding
  287.  * slots in the subs array so that they are Initial instances.
  288.  *)
  289. fun getSigSlots (sign, path, subs, typs) =
  290.     let fun newInstance (signat, path) =
  291.               Initial {signat=signat, path=path, parent_typs=typs,
  292.                        inherited=ref []}
  293.         fun f (name, pos, signat) =
  294.              let val sl = {base=subs, offset=pos}
  295.              in set (sl, newInstance (signat, name::path));
  296.                 (name, SLOTstr sl)
  297.              end
  298.     in map f (getSubSigs sign)
  299.     end
  300.  
  301. (* Finds all types in a signature, and updates the corresponding slots
  302.  * in the typs array so that they are tInitial instances.
  303.  *)
  304. fun getSigTSlots (sign, path, typs) =
  305.     let fun newInstance (tycon, path) =
  306.     (tprint "<tNULLinstance converted to tInitial>\n";
  307.      tInitial {tycon=tycon, path=path, inherited=ref []})
  308.         fun f (name, pos, tycon) =
  309.              let val sl = {base=typs, offset=pos}
  310.              in set (sl, newInstance (tycon, name::path));
  311.                 (name, SLOTtyc sl)
  312.              end
  313.     in map f (getTypes sign)
  314.     end
  315.  
  316.  
  317. (***********************************************************************
  318.  * This function merges a node into a class.  It does so by looking    *
  319.  * up the elements the node requires in the "union" environment for    *
  320.  * the class.  If a binding does not exist, then one is added to the   *
  321.  * union.  If a binding does exist to some other node for the symbol,  *
  322.  * then constraints are added to both nodes indicating that they are   *
  323.  * equivalent.                                                         *
  324.  ***********************************************************************)
  325. fun merge (union, defined, err, path) (sym, rep) =
  326.     (case (Env.look (!union,sym), rep)
  327.      of (extrep as EXTstr _, SLOTstr sl)
  328.         => (case get sl
  329.             of Initial {inherited, ...}
  330.                  => (push inherited 
  331.                {my_path=[], its_ancestor=extrep, its_path=[]};
  332.              union := Env.bind (sym,rep,!union))
  333.          | ERRORinstance => ()
  334.              | _ => impossible "Instantiate:merge.1")
  335.       | (SLOTstr sl, extrep as EXTstr _)
  336.         => (case get sl
  337.             of Initial {inherited, ...}
  338.                  => push inherited 
  339.                {my_path=[], its_ancestor=extrep, its_path=[]}
  340.              | ERRORinstance => (error_found := true)
  341.              | _ => impossible "Instantiate:merge.2")
  342.       | (SLOTstr sl1, SLOTstr sl2)
  343.         => (case (get sl1, get sl2)
  344.             of (Initial {inherited=inherited1, ...},
  345.                 Initial {inherited=inherited2, ...})
  346.                  => (push inherited1 
  347.                        {my_path=[], its_ancestor=rep, its_path=[]};
  348.                      push inherited2 
  349.                {my_path=[], its_ancestor=SLOTstr sl1, its_path=[]})
  350.          | (ERRORinstance,_) => ()
  351.          | (_,ERRORinstance) => ()
  352.              | _ => impossible "Instantiate:merge.3")
  353.       | (extrep as EXTtyc _, SLOTtyc sl)
  354.         => (case get sl
  355.             of tInitial {inherited, ...}
  356.                  => (push inherited 
  357.                {my_path=[], its_ancestor=extrep, its_path=[]};
  358.                      union := Env.bind (sym,rep,!union))
  359.          | tERRORinstance => ()
  360.              | _ => impossible "Instantiate:merge.4")
  361.       | (SLOTtyc sl, extrep as EXTtyc _)
  362.         => (case get sl
  363.             of tInitial {inherited, ...}
  364.                  => push inherited 
  365.                {my_path=[], its_ancestor=extrep, its_path=[]}
  366.              | tERRORinstance => ()
  367.              | _ => impossible "Instantiate:merge.5")
  368.       | (SLOTtyc sl1, SLOTtyc sl2)
  369.         => (case (get sl1, get sl2)
  370.             of (tInitial {inherited=inherited1, ...},
  371.                 tInitial {inherited=inherited2, ...})
  372.                  => (push inherited1 
  373.                {my_path=[], its_ancestor=rep, its_path=[]};
  374.                      push inherited2 
  375.                {my_path=[], its_ancestor=SLOTtyc sl1, its_path=[]})
  376.              | (tERRORinstance,_) => ()
  377.              | (_,tERRORinstance) => ()
  378.              | _ => impossible "Instantiate:merge.6")
  379.       | _ => impossible "Instantiate:merge.7")
  380.      handle Env.Unbound
  381.        => case defined
  382.           of SOME str =>
  383.                err WARN 
  384.            ("This signature cannot be matched : sharing "
  385.                             ^(pathName path)^" = "^(strName str)
  386.                             ^" : "^(strName str)^" has no "
  387.                             ^(Symbol.name sym)^" component.")
  388.            nullErrorBody
  389.            | NONE => union := Env.bind (sym,rep,!union)
  390.  
  391. (*************************************************************************
  392.  * This function just checks to make sure that each of the bindings      *
  393.  * that a class requires actually exits in the origin of some [external] *
  394.  * structure.                                                            *
  395.  *************************************************************************)
  396. fun check_def (union,str,err,path) =
  397.       let val env = case (getOrigin str) 
  398.               of (SIMPLE{env,...}) => env
  399.                | (INSTANCE{sign=SIG{env,...},...}) => !env
  400.                | ERROR_STR => (error_found := true; Env.empty)
  401.                | _ => impossible "instantiate:check_def"
  402.       val path' = getStrPath str
  403.       fun check (sym, binding) =
  404.         (Env.look (env,sym); ())
  405.           handle Env.Unbound =>
  406.           err WARN 
  407.                     ("This signature cannot be matched : sharing "
  408.              ^(pathName(path'))^" = "^(pathName path)^" : "
  409.              ^(pathName(path'))
  410.              ^" is also sharing with a structure with a "
  411.              ^(Symbol.name sym)^" component, and "^(pathName path)
  412.             ^" has no "^(Symbol.name sym)^" component.")
  413.             nullErrorBody
  414.   in
  415.       Env.app check (!union)
  416.   end
  417.  
  418. (**************************************************************************
  419.  * This function distributes the structure sharing constraints that a     *
  420.  * signature has to the children of a corresponding node.  Note that this *
  421.  * only deals with the explicit constraints.  Implied and inherited       *
  422.  * constraints are propogated by merge and the constrain functions of     *
  423.  * explore_class and explore_tclass.                                      *
  424.  **************************************************************************)
  425. fun distributeS 
  426.       (sign as SIG {kind=ref(TOP{sConstraints,...}),...}, subs, err) =
  427.     let exception DistributeS
  428.     fun f (sym::path) =
  429.             let val pos = (getSigPos sign sym)
  430.             in case subs sub pos
  431.                of Initial {inherited, ...}
  432.                     => (path, inherited, SLOTstr {base=subs, offset=pos})
  433.           | ERRORinstance => raise DistributeS
  434.                   | _ => impossible "distributeS:f DD134"
  435.             end
  436.           | f [] = impossible "distributeS:f DD148"
  437.     fun dist {internal=(p::rest),external} = 
  438.         let val (p1, h1, ir1) = f p
  439.         fun g (p2, h2, ir2) =
  440.             (push h1 {my_path=p1, its_path=p2, its_ancestor=ir2};
  441.              push h2 {my_path=p2, its_path=p1, its_ancestor=ir1})
  442.         in
  443.         app (fn p' => g (f p')) rest;
  444.         case external of
  445.             NONE => ()
  446.           | SOME str => push h1 
  447.             {my_path=p1,its_ancestor=EXTstr (getOrigin str),
  448.              its_path=[]}
  449.         end
  450.       | dist {internal=[],...} = ()
  451.     in (app dist sConstraints) handle DistributeS => ()
  452.     end
  453.   (* don't have any sharing constraints to *)
  454.   (* distribute if we don't have a TOP sig *)
  455.   | distributeS _ = () 
  456.  
  457. (***************************************************************************
  458.  * This function distributes the type sharing constraints that a signature *
  459.  * has to the children of the corresponding node.                          *
  460.  ***************************************************************************)
  461. fun distributeT 
  462.       (sign as SIG {kind=ref(TOP{tConstraints, ...}),...},subs,typs,err) =
  463.     let exception DistributeT
  464.     fun f [sym] =
  465.               let val pos = getSigTPos sign sym
  466.               in case typs sub pos
  467.                  of tInitial {inherited, ...}
  468.                       => ([], inherited, SLOTtyc {base=typs, offset=pos})
  469.          | tERRORinstance => raise DistributeT
  470.                  | _ => impossible "distributeT:f DD144"
  471.               end
  472.           | f (sym::path) =
  473.               let val pos = (getSigPos sign sym)
  474.             in case subs sub pos
  475.                of Initial {inherited, ...}
  476.                     => (path, inherited, SLOTstr {base=subs, offset=pos})
  477.                   | _ => impossible "distributeT:f DD146"
  478.             end
  479.           | f [] = impossible "distributeT:f DD147"
  480.     fun dist {internal=p::rest,external} = 
  481.         let val (p1,h1,ir1) = f p
  482.         fun g (p2, h2, ir2) =
  483.             (push h1 {my_path=p1, its_path=p2, its_ancestor=ir2};
  484.              push h2 {my_path=p2, its_path=p1, its_ancestor=ir1})
  485.         in
  486.         app (fn p' => g (f p')) rest;
  487.         case external of
  488.             NONE => ()
  489.           | SOME tyc => push h1 {my_path=p1,its_ancestor=EXTtyc tyc,its_path=[]}
  490.         end
  491.       | dist {internal=[],...} = ()
  492.     in (app dist tConstraints) handle DistributeT => ()
  493.     end
  494.   (* don't have any sharing constraints to *)
  495.   (* distribute if we don't have a TOP sig *)
  496.   | distributeT _ = () 
  497.  
  498. exception ExploreInst of Symbol.symbol list
  499.  
  500. (***************************************************************************
  501.  * This is the main function of the algorithm.  Given an Initial node, 
  502.  * it creates subs and typs arrays and converts the node to a Partial
  503.  * node.  This step is skipped if the node has been explored previously
  504.  * and is already Partial.  Then, we find all of the child nodes of
  505.  * the node, create Initial instances of them, apply merge to them
  506.  * resulting in a new union_components enviornment.  We then distribute
  507.  * all of the sharing constraints to the new children and apply
  508.  * the constrain function to our list of inherited constraints.  Constrain
  509.  * in turn uses the constraints to track down other nodes that should
  510.  * be placed in the same equivalence class.  If the ancestors of such
  511.  * a node have not been explored yet, then they are explored first.
  512.  * Once constrain is complete, class holds a list of instance nodes
  513.  * (all Partial) that are equivalent and union_components holds an 
  514.  * enviornment that maps the "union" of all components in the class
  515.  * to instreps.  A class_origin is [lazily] built.  (The origin will
  516.  * be available iff there is an external sharing constraint.)  Finally,
  517.  * we apply the function finalize to each member of the class which
  518.  * converts each of the Partial nodes to either Final_top or Final_embed
  519.  * nodes.  
  520.  *
  521.  * This has been slightly modified so that if two slots in the class
  522.  * have nodes that share the same signature, then the slots are made
  523.  * to point to only one of the nodes.  Of course, the sharing constraints
  524.  * for both must be propogated to the descendants.  
  525.  ***************************************************************************)
  526. fun explore_class (first_slot : instance slot, 
  527.            class_depth: int, 
  528.            err: severity -> string -> (PrettyPrint.ppstream -> unit)
  529.                 -> unit)
  530.                   : unit =
  531.     let 
  532.     val union_components = ref (Env.empty : instrep Env.env)
  533.         val class = ref ([] : instance slot list)
  534.         val class_def = ref (NONE : Structure option)
  535.     exception Error_Sig
  536.     (* Convert the node from Initial to Partial.  Merge its components
  537.      * into the union.  Push down any sharing constraints it has in 
  538.          * its signature.  Then apply constrain to each of the inherited
  539.          * constraints.
  540.          *)
  541.         fun explore_inst (sl: instance slot) : unit =
  542.             (case (get sl) of
  543.          ERRORinstance => ()
  544.            | (Partial {depth, path, ...}) =>
  545.              if (depth = class_depth) then ()
  546.              else raise ExploreInst path
  547.            | (Initial {signat, path, parent_typs, inherited}) =>
  548.              let fun find_same_sig [] = false
  549.                | find_same_sig (sl'::rest) =
  550.                  (case (get sl')
  551.                 of (p as (Partial{signat=signat',
  552.                           subs,typs,
  553.                           path=path',...})) =>
  554.                     (if eqSignature(signat,signat') then
  555.                      (set (sl,p);
  556.                       push class sl;
  557.                       app (constrain (signat, subs,
  558.                               typs, path))
  559.                         (!inherited);
  560.                       true)
  561.                      else
  562.                      find_same_sig rest)
  563.                  | ERRORinstance => false
  564.                  | _ => impossible 
  565.                           "Instantiate:find_same_sig")
  566.              in
  567.              if not(find_same_sig(!class)) then 
  568.             (let val subs = 
  569.                    case signat
  570.                    of SIG {kind=ref(TOP {strcount, ...}), ...} =>
  571.                          array (strcount, NULLinstance)
  572.                     | SIG {kind=ref IRRELEVANT, ...} =>
  573.                          impossible "can't instantiate IRRELEVANT"
  574.                     | SIG {kind=ref EMBEDDED, ...} => #base sl
  575.                     | ERROR_SIG => raise Error_Sig
  576.                                 | FULL_SIG =>  raise Error_Sig
  577.                  val typs = 
  578.                    case signat
  579.                    of SIG {kind=ref(TOP {typecount,...}),...} =>
  580.                     array (typecount, tNULLinstance)
  581.                 | SIG {kind=ref EMBEDDED, ...} => 
  582.                       parent_typs
  583.                 | _ => impossible
  584.                       "Instantiate::explore_class.2"
  585.              in 
  586.              set (sl, Partial {signat=signat,
  587.                        path=path,subs=subs,
  588.                        typs=typs,
  589.                        final_rep = ref NONE,
  590.                        depth=class_depth});
  591.              push class sl;
  592.              app (merge (union_components, !class_def, 
  593.                      err, path))
  594.                (getSigSlots (signat, path, subs, typs));
  595.              app (merge (union_components, !class_def, 
  596.                      err, path))
  597.                (getSigTSlots (signat, path, typs));
  598.              distributeS (signat, subs, err);
  599.              distributeT (signat, subs, typs, err);
  600.              app (constrain (signat, subs, typs, path)) 
  601.                (!inherited)
  602.                  end) handle Error_Sig => (error_found := true;
  603.                                set (sl,ERRORinstance))
  604.              else () 
  605.              end
  606.            | _ => if (!error_found) then (set (sl,ERRORinstance))
  607.               else (impossible "Instantiate:explore_class.3"))
  608.  
  609.     (* Class shares with some external structure *)
  610.  
  611.         and constrain (signat, subs, _, path)
  612.                   {my_path=[], its_ancestor=EXTstr str,...} =
  613.         (case !class_def
  614.            of SOME str' => (tprint "<checking eqOrigin>\n";
  615.                 if eqOrigin(str',str) then ()
  616.                 else 
  617.                    err COMPLAIN
  618.                    ("Inconsistent defining constraints : "
  619.                    ^(strName str')^" = "^(strName str))
  620.                    nullErrorBody)
  621.         | NONE => (class_def := SOME str;
  622.                app (merge (union_components, NONE, err, []))
  623.                    (getStrSlots str);
  624.                app (merge (union_components, NONE, err, []))
  625.                    (getStrTSlots str);
  626.                check_def (union_components, str, err, path)))
  627.  
  628.       (* Class shares with the structure in slot -- explore it *)
  629.  
  630.           | constrain (signat, subs, _, path)
  631.                   {my_path=[],its_ancestor=SLOTstr slot,its_path=[]} =
  632.         (tprint "<calling explore_inst to add member to equiv class>\n";
  633.          explore_inst slot handle (ExploreInst path') =>
  634.         (err COMPLAIN
  635.           "Sharing constraint is also sharing with a substructure"
  636.           nullErrorBody;
  637.              set (slot, ERRORinstance)))
  638.  
  639.       (* Class shares with another structure.  Make sure its ancestor
  640.        * has been explored.  Then push the constraint down a level.
  641.        *)
  642.  
  643.           | constrain (signat, subs', typs, path')
  644.                   {my_path=[],its_ancestor=SLOTstr slot,
  645.                its_path=sym::rest} =
  646.         (case (get slot)
  647.            of Initial _ => 
  648.                (tprint "<Having to call explore class on an ancestor ";
  649.             tprint "of a node I'm equivalent to.>\n";
  650.             explore_class (slot, (class_depth+1), err)
  651.                   handle (ExploreInst _) => 
  652.               impossible "Instantiate:explore_class.4")
  653.         | ERRORinstance => ()
  654.         | _ => ();
  655.          tprint "<finished exploring his ancestor>\n";
  656.          case (get slot)
  657.            of Final_top {sign, subs, ...} =>
  658.            (tprint "<calling constrain recursively>\n";
  659.             constrain (signat, subs', typs, path')
  660.               {my_path=[], its_path=rest,
  661.                its_ancestor=SLOTstr {base=subs,
  662.                          offset=getSigPos sign sym}})
  663.         | Final_embed {sign, subs, ...} =>
  664.               (tprint "<found Final_embed>\n";
  665.                constrain (signat, subs', typs, path')
  666.                 {my_path=[], its_path=rest,
  667.              its_ancestor=SLOTstr {base=subs,
  668.                            offset=getSigPos sign sym}})
  669.            | Partial _ =>
  670.            (err COMPLAIN
  671.               "Sharing constraint is also sharing with a substructure"
  672.               nullErrorBody;
  673.             set (slot,ERRORinstance))
  674.            | ERRORinstance => ()
  675.            | _ => impossible "Instantiate:explore_class.5")
  676.  
  677.  
  678.       (* One of the nodes children shares with someone.  Push the
  679.        * constraint down to the child now that we are explored.
  680.        *)
  681.  
  682.       | constrain (signat, subs, typs, _) 
  683.                   {my_path=sym::rest, its_ancestor, its_path} =
  684.         (case getSigPosGen signat sym
  685.            of TYCbind (FORMtyc {pos, ...}) =>
  686.            (case typs sub pos
  687.               of tInitial {inherited, ...} =>
  688.               push inherited {my_path=[], 
  689.                       its_ancestor=its_ancestor, 
  690.                       its_path=its_path}
  691.                | _ => impossible "Instantiate:explore_class.6")
  692.         | STRbind (STRvar {binding=STR_FORMAL {pos, ...}, ...}) =>
  693.               (case subs sub pos
  694.              of Initial {inherited, ...} =>
  695.                  push inherited {my_path=rest, 
  696.                          its_ancestor=its_ancestor, 
  697.                          its_path=its_path}
  698.               | _ => impossible 
  699.                     "Instantiate:explore_class.7")
  700.          | _ => impossible "Instantiate:explore_class.8")
  701.       | constrain _ _ = impossible "Instantiate:explore_class.9"
  702.  
  703.  
  704.     (* Should find everyone in the equiv. class and convert them to 
  705.      * Partial nodes.  
  706.      *)
  707.         val _ = explore_inst first_slot;
  708.  
  709.     val class_origin = 
  710.           ref (case !class_def
  711.              of SOME str => BUILT (getOrigin str)
  712.               | NONE => 
  713.               (case !class
  714.                  of [x] => NEED_SELF
  715.                   | (_::_) => NEED_SIMPLE (!union_components)
  716.                   | _ => if (!error_found) then NEED_SELF
  717.                      else impossible
  718.                        "Instantiate.explore_class.10"))
  719.  
  720.     (* Converts all of the nodes in the class (which should be Partial)
  721.      * to Final nodes.  Note that nodes which share the same signature
  722.      * should share the same Final nodes.  So, they are memoized using
  723.      * the final_rep field of the Partial node.
  724.      *)
  725.     fun finalize sl =
  726.         (case (get sl) 
  727.            of ERRORinstance => ()
  728.             | Partial {signat, path, subs, typs, final_rep, ...} =>
  729.            (case (!final_rep) of
  730.             SOME f => (set (sl, f))
  731.               | NONE =>
  732.                 case signat of
  733.                 SIG {env,
  734.                      kind=ref (TOP{strcount,typecount,...}),
  735.                                      ...} =>
  736.                 let val strArray = array (strcount, ERROR_STR)
  737.                     val tycArray = array (typecount, ERRORtyc)
  738.                     val f = 
  739.                     Final_top {sign = signat,
  740.                            origin_info=class_origin,
  741.                            actual_subStrs = strArray,
  742.                            actual_types = tycArray,
  743.                            subs = subs,
  744.                            typs = typs,
  745.                            final_struct = ref NONE,
  746.                            expanded = ref false}
  747.                 in 
  748.                     final_rep := SOME f;
  749.                     set (sl, f)
  750.                 end
  751.               | SIG {env, kind=ref EMBEDDED, ...} =>
  752.                 (set (sl, 
  753.                       Final_embed {sign=signat, path=path,
  754.                            origin_info = class_origin,
  755.                            subs=subs, 
  756.                            typs=typs,
  757.                            expanded=ref false}))
  758.               | _ => impossible 
  759.                    "Instantiate:explore_class.12")
  760.         | _ => impossible "Instantiate:explore_class.11")
  761.     in 
  762.     app finalize (!class)
  763.     end (* explore_class *)
  764.  
  765. (*************************************************************************
  766.  * This function deals with exploration of type nodes in the instance
  767.  * graph and is similar to the explore_class function above.  It is
  768.  * a bit simpler since it doesn't have to worry about "children" of
  769.  * type nodes.  However, we must check that the arities of equivalenced
  770.  * types are the same.  Also, if they have constructors, we must check
  771.  * to see that they have the same constructor names.  We don't know how
  772.  * to check that the types of the constructors are satisfiable -- this
  773.  * involves a limited form of second-order unification.
  774.  *************************************************************************)
  775. fun explore_tclass (first_slot, make_stamp, err, argOption) =
  776.     let val class = ref ([] : type_ins slot list)
  777.         val class_def = ref (NONE : tycon option)
  778.     fun substParam p NONE = p
  779.       | substParam [] _ = []
  780.       | substParam p (SOME s) = (
  781.           case rev p 
  782.           of (head::tail) => if head=name_X then rev (s::tail) else p 
  783.            | [] => impossible "substParam")
  784.         fun explore_inst sl =
  785.               (case get sl
  786.                of tPartial _ => ()
  787.                 | tInitial {tycon, path, inherited} =>
  788.                     (tprint "<setting tInitial to tPartial>\n";
  789.              set (sl, tPartial {tycon=tycon, path=path});
  790.                      push class sl;
  791.                      app constrain (!inherited))
  792.         | tERRORinstance => ()
  793.                 | _ => impossible "Instantiate:explore_tclass.1")
  794.         and constrain {my_path=[], its_ancestor=EXTtyc tyc, ...} =
  795.               (case !class_def
  796.                of SOME tyc' =>
  797.                     if equalTycon (tyc',tyc)
  798.                     then ()
  799.                     else
  800.             let val s1 ="Inconsistent defining constraints : type "
  801.                 val s2 = (Symbol.name (tycName tyc')) ^ " = "
  802.                 val s3 = (Symbol.name (tycName tyc))
  803.                 val s = s1 ^ (s2 ^ s3)
  804.             in
  805.                 err COMPLAIN s nullErrorBody
  806.             end
  807.                 | NONE => class_def := SOME tyc)
  808.           | constrain {my_path=[], its_ancestor=SLOTtyc slot, its_path=[]} =
  809.               explore_inst slot
  810.           | constrain {my_path=[],its_ancestor=SLOTstr slot,its_path=sym::rest}
  811.         =
  812.               (case get slot
  813.          of Initial _ =>
  814.              (explore_class (slot, 0, err)
  815.               handle ExploreInst _ => 
  816.               impossible "Instantiate:explore_tclass.2")
  817.            | _ => ();
  818.                case (get slot, rest)
  819.          of (Final_top {sign, typs, ...}, []) =>
  820.                   constrain {my_path=[], its_path=[],
  821.                    its_ancestor=
  822.                    SLOTtyc {base=typs,
  823.                         offset=getSigTPos sign sym}}
  824.           | (Final_top {sign, subs, ...}, _) =>
  825.             constrain {my_path=[], its_path=rest,
  826.                    its_ancestor=
  827.                    SLOTstr {base=subs,
  828.                         offset=getSigPos sign sym}}
  829.           | (Final_embed {sign, typs, ...}, []) =>
  830.             constrain {my_path=[], its_path=[],
  831.                    its_ancestor=
  832.                    SLOTtyc {base=typs,
  833.                         offset=getSigTPos sign sym}}
  834.           | (Final_embed {sign, subs, ...}, _) =>
  835.             constrain {my_path=[], its_path=rest,
  836.                    its_ancestor=
  837.                    SLOTstr {base=subs,
  838.                         offset=getSigPos sign sym}}
  839.           | (ERRORinstance, _) => ()
  840.           | _ => impossible "Instantiate:explore_tclass.3")
  841.           | constrain _ = 
  842.           impossible "Instantiate:explore_tclass:constrain.4"
  843.  
  844.         val _ = explore_inst first_slot
  845.  
  846.     exception GetProps
  847.  
  848.         fun getProps sl =            (* DEFtycs are not yet allowed in sigs. *)
  849.             case get sl
  850.           of (tPartial {tycon=
  851.                 FORMtyc {spec=GENtyc {arity,eq,kind,...}, ...},
  852.                 path,...})
  853.           => (arity, eq, path, kind)
  854.         | tERRORinstance => raise GetProps
  855.         | tPartial{tycon,...} =>
  856.             ErrorMsg.impossibleWithBody
  857.               "Instantiate.getProps: wrong kind of tycon"
  858.               (fn ppstrm =>
  859.                (PPType.ppTycon Env.empty ppstrm tycon;
  860.             PrettyPrint.add_newline ppstrm))
  861.         | _ => impossible "Instantiate:explore_tclass:getProps"
  862.  
  863.     exception GetPos
  864.  
  865.         fun getPos sl' =
  866.             case get sl'
  867.           of (tPartial{tycon=FORMtyc {pos, ...},...}) => pos
  868.            | tERRORinstance => (raise GetPos)
  869.            | _ => impossible "Instantiate:explore_tclass:getPos"
  870.  
  871.         fun check_arity (ar1, ar2, path1, path2) =
  872.             if ar1 = ar2 then ()
  873.             else err COMPLAIN 
  874.                      ("Inconsistent arities in sharing type "
  875.                       ^(pathName path1)^" = "^(pathName path2)^" : "
  876.                       ^(pathName path1)^" has arity "^(makestring ar1)^" and "
  877.                       ^(pathName path2)^" has arity "^(makestring ar2)^".")
  878.              nullErrorBody
  879.     val sortD = Sort.sort
  880.         (fn (DATACON{name=name1,...},DATACON{name=name2,...}) =>
  881.          Symbol.symbolGt(name1,name2))
  882.  
  883.     fun eqDataCons (DATACON{name=name1,...},DATACON{name=name2,...}) =
  884.         Symbol.eq(name1,name2)
  885.  
  886.     fun compareD ([], []) = true
  887.       | compareD (d1::r1, d2::r2) = 
  888.         eqDataCons(d1,d2) andalso compareD (r1,r2)
  889.       | compareD _ = false
  890.             
  891.     val class_tycons = ref 
  892.         (case (!class_def) of
  893.         NONE => (NONE : datacon list option)
  894.           | SOME (GENtyc {kind=ref (DATAtyc datacons),...}) =>
  895.             (SOME (sortD datacons))
  896.           | SOME (DEFtyc {tyfun=TYFUN{body=ty,...},...}) =>
  897.             (case (headReduceType ty) of
  898.              CONty (GENtyc {kind = ref (DATAtyc datacons),...},_) 
  899.              => (SOME (sortD datacons))
  900.                | _ => NONE)
  901.           | SOME (_) => (NONE : datacon list option))
  902.  
  903.     fun check_kind (ref (DATAtyc datacons), path) = 
  904.         (case (!class_tycons) of
  905.          NONE => class_tycons := (SOME (sortD datacons))
  906.            | SOME (dcs) => 
  907.              if (compareD (dcs,datacons)) then ()
  908.              else err COMPLAIN
  909.              ("Inconsistent constructors in sharing datatype "
  910.               ^(pathName path)^".")
  911.              nullErrorBody)
  912.       | check_kind _ = ()
  913.  
  914.         val finalize =
  915.             case !class_def
  916.             of SOME (GENtyc {stamp, arity,eq=ref eq, kind, path})
  917.                => (fn sl
  918.                       => let val (arity', _, path', kind') = getProps sl
  919.                  val path'' = substParam path' argOption
  920.                              val result = GENtyc {stamp=stamp, arity=arity,
  921.                                                   eq=ref eq,
  922.                           kind=kind, path=path''}
  923.                          in check_arity (arity, arity', path, path');
  924.                 check_kind (kind',path');
  925.                             set (sl, tFinal result)
  926.                          end)
  927.              | SOME (DEFtyc {path, strict, tyfun as TYFUN {arity, ...}})
  928.                => (fn sl
  929.                       => (let val (arity', _, path', kind') = getProps sl
  930.                   val path'' = substParam path' argOption
  931.                               val result = DEFtyc {path=path'',
  932.                             strict=strict,
  933.                            tyfun=tyfun}
  934.                           in check_arity (arity, arity', path, path');
  935.                  check_kind (kind',path');
  936.                              set (sl, tFinal result)
  937.               end) handle GetProps => (error_found := true;
  938.                            set (sl,tERRORinstance)))
  939.              | SOME _ => impossible "Instantiate:explore_tclass.5"
  940.              | NONE
  941.                => case !class
  942.                   of (sl::rest)
  943.                      => ((let val (arity, _, path, kind) = getProps sl
  944.                   val stamp = make_stamp ()
  945.                in fn sl'
  946.                            => ((let val (arity',ref eq',
  947.                     path',kind') = getProps sl'
  948.                    val path'' = substParam path' argOption
  949.                    val pos = getPos sl'
  950.                    val tyc = GENtyc {stamp=stamp, arity=arity,
  951.                              eq=ref eq', path=path'',
  952.                              kind=kind'}
  953.                    in check_arity (arity, arity', path, path');
  954.                   check_kind (kind',path');
  955.                   set (sl', tFinal tyc)
  956.                    end) handle GetProps => 
  957.                                    (error_found := true;
  958.                         set (sl',tERRORinstance))
  959.                              | GetPos => 
  960.                            (error_found := true;
  961.                         set (sl',tERRORinstance)))
  962.               end) handle GetProps => 
  963.                 (error_found := true;
  964.                  set (sl,tERRORinstance); (fn _ => ())))
  965.                    | [] => impossible "Instantiate:explore_tclass.6"
  966.     in 
  967.     app finalize (!class)
  968.     end (* explore_tclass *)
  969.  
  970. fun sig_to_instance (sign, path, makeStamp, err,argOption) : instance =
  971.  
  972.         let val dummy = array (1, Initial {signat=sign, path=path, 
  973.                        inherited=ref [],
  974.                        parent_typs=arrayoflist []})
  975.  
  976.     fun expand ERRORinstance = ()
  977.       | expand (Final_top {expanded=ref true,...}) = ()
  978.       | expand (Final_top {actual_subStrs,actual_types,sign,subs,
  979.                    typs, expanded,...}) = 
  980.         (* We must expand the Final_top instance in a top-down 
  981.          * fashion.  So, we iterate through the bindings, updating
  982.          * the subs array appropriately.  As we encounter a
  983.          * sub signature or type, we recursively expand it.
  984.          *)
  985.         let fun expand_substr (subs, typs, actual_types) (sym,i,spec) =
  986.            (tprint "<Expanding substr ";
  987.             tprintSym sym; tprint ">\n";
  988.             (if sym=name_P then
  989.                        update(subs,i,ERRORinstance) 
  990.                      else
  991.              case (subs sub i)
  992.               of Initial _ =>
  993.               (tprint "<substr was Initial, exploring class>\n";
  994.                explore_class ({base=subs, offset=i},0,err)
  995.                handle ExploreInst _
  996.                 => impossible "instantiate.2")
  997.                | Partial _ => (tprint "<substr already partial>\n")
  998.                | _ => (tprint "<substr already final>");
  999.              case (subs sub i)
  1000.               of (inst as (Final_top _)) =>
  1001.               (tprint "<Going into substrs of top>\n";
  1002.                expand inst)
  1003.                | Final_embed {sign,...} =>
  1004.                (tprint "<substr was embedded, going recursive>\n";
  1005.                 app (expand_substr (subs, typs, actual_types))
  1006.                                     (getSubSigs sign);
  1007.                 tprint "<Expanding types of substructure>\n";
  1008.                 app (expand_type (typs, actual_types))
  1009.                                     (getTypes sign))
  1010.                | ERRORinstance => ()
  1011.                | _ => impossible "instantiate.3"))
  1012.  
  1013.                 and expand_type (typs,actual_types) (sym,i,_) =
  1014.                     (tprint "<Expanding type ";
  1015.              tprintSym sym; tprint ">\n";
  1016.              case (typs sub i)
  1017.               of tInitial _ =>
  1018.                explore_tclass ({base=typs, offset=i}, makeStamp, 
  1019.                        err,argOption)
  1020.                | _ => ();
  1021.              tprint "<Plugging typ into actual_types>\n";
  1022.                      case (typs sub i)
  1023.               of tFinal tycon => update (actual_types, i, tycon)
  1024.                | tERRORinstance => update (actual_types, i, ERRORtyc)
  1025.                | _ => impossible"instantiate.4")
  1026.              in 
  1027.         expanded := true;
  1028.         tprint "<Expanding...\n>";
  1029.         case (getSubSigs sign)
  1030.             of [] => (tprint "<No sub sigs>\n")
  1031.              | l => (tprint "<app'ing expand_substr>\n";
  1032.                  app (expand_substr (subs,typs,actual_types)) l);
  1033.         case (getTypes sign)
  1034.             of [] => (tprint "<No sub types>\n")
  1035.              | l => (tprint "<app'ing expand_type>\n";
  1036.                  app (expand_type (typs,actual_types)) l)
  1037.             end
  1038.       | expand _ = impossible "instantiate:expand"
  1039.  
  1040.     in 
  1041.     ((explore_class ({base=dummy,offset=0},0,err))
  1042.      handle (ExploreInst _) =>
  1043.          impossible "instantiate.1");
  1044.     expand (dummy sub 0);
  1045.     (dummy sub 0)
  1046.     end
  1047.  
  1048. (*************************************************************************
  1049.  * This function takes an instance graph (assuming that the root node is
  1050.  * a Final_top node) and creates a structure corresponding to the graph.
  1051.  * It does so by building the graph bottom up.  When an origin structure
  1052.  * is needed, we look at the node and determine if one is already BUILT
  1053.  * or not.  If we need to build a SIMPLE origin, then we are given an
  1054.  * instrep env which we iterate over.  For each of the elements, we
  1055.  * recursively generate origin structures.
  1056.  * 
  1057.  * Structures that are constructed for Final_top nodes are memoized
  1058.  * (using the final_struct field) so that if two slots in the graph
  1059.  * point to the same node, they can use the same instance structure.
  1060.  ************************************************************************)
  1061. fun instance_to_structure (path,make_stamp)
  1062.     (instance as (Final_top {sign,actual_subStrs,actual_types,
  1063.                  subs,final_struct,...})) =
  1064.     (case (!final_struct) of
  1065.      SOME str => str
  1066.        | NONE =>
  1067.         let exception Get_Origin
  1068.  
  1069.                 val fct_array =
  1070.                   case sign
  1071.                   of SIG{kind=ref (TOP{fctcount,...}),...} =>
  1072.                        Array.array (fctcount,ERROR_FCT)
  1073.                    | _ => Array.arrayoflist []
  1074.  
  1075.         fun instrep_to_binding (sym, instrep) =
  1076.             (case instrep of
  1077.              EXTstr str => 
  1078.                  STRbind (STRvar {name = sym,
  1079.                           access = PATH [0],
  1080.                           binding=str})
  1081.                | SLOTstr sl => 
  1082.                  STRbind 
  1083.                  (STRvar {name = sym,
  1084.                       access = PATH [0],
  1085.                       binding=get_origin(get sl)
  1086.                       })
  1087.                | EXTtyc tyc => TYCbind tyc
  1088.                | SLOTtyc sl =>
  1089.                  TYCbind 
  1090.                  (case (get sl)
  1091.                 of tFinal tyc => tyc
  1092.                  | tERRORinstance => ERRORtyc
  1093.                  | _ => impossible
  1094.                        "Instantiate:make_simple"))
  1095.  
  1096.         and make_simple (env: instrep Env.env) =
  1097.             let val str_env = ref Env.empty
  1098.             fun inst_to_binding (sym, instrep) =
  1099.                 let val binding = instrep_to_binding (sym, instrep)
  1100.                 in 
  1101.                 str_env := Env.bind(sym,binding,!str_env)
  1102.                 end
  1103.             in 
  1104.             Env.app inst_to_binding env;
  1105.             SIMPLE {stamp = make_stamp (),
  1106.                 env = (!str_env),
  1107.                 path = []}
  1108.             end
  1109.  
  1110.         (* Gets the origin of an instance -- builds one if one is not
  1111.          * already built. 
  1112.          *)
  1113.         and get_origin instance =
  1114.             (let val origin_info = case instance of
  1115.              (Final_top {origin_info,...}) => origin_info
  1116.                | (Final_embed {origin_info,...}) => origin_info
  1117.                | ERRORinstance => raise Get_Origin
  1118.                | _ => impossible "Instantiate:get_origin"
  1119.              in
  1120.              (case (!origin_info) of
  1121.                   BUILT str => str
  1122.                 | NEED_SELF => (let val orig = SELF (make_stamp())
  1123.                         in
  1124.                         origin_info := BUILT orig;
  1125.                         orig
  1126.                         end)
  1127.                 | NEED_SIMPLE env => 
  1128.                   let val orig = make_simple env
  1129.                   in
  1130.                       origin_info := BUILT orig;
  1131.                       orig
  1132.                   end)
  1133.             end) handle Get_Origin => ERROR_STR
  1134.  
  1135.         (* Creates a structure node from the instance node found at
  1136.          * position i and plugs it into the actual_subStrs array 
  1137.          * for the current node.  If the structure is embedded, we 
  1138.          * must recurse.
  1139.          *)
  1140.         fun inst_to_struct (sym,i,_) =
  1141.             (case (subs sub i) of
  1142.              (inst as (Final_top _)) =>
  1143.                  let val str = 
  1144.                    instance_to_structure 
  1145.                    (sym::path,make_stamp) inst
  1146.                  in
  1147.                  update (actual_subStrs,i,str)
  1148.                  end
  1149.                | (inst as (Final_embed 
  1150.                    {sign,subs,typs,origin_info,...})) =>
  1151.              (let val orig = get_origin inst
  1152.                   val _ = app inst_to_struct (getSubSigs sign);
  1153.                   val str = INSTANCE {sign=sign,
  1154.                           origin=orig,
  1155.                           subStrs=actual_subStrs,
  1156.                                                   subFcts=fct_array,
  1157.                           path=sym::path,
  1158.                           types=actual_types}
  1159.               in
  1160.                   update(actual_subStrs,i,str)
  1161.               end)
  1162.                | ERRORinstance => (update (actual_subStrs,i,ERROR_STR))
  1163.                | _ => impossible 
  1164.                     "Instantiate:inst_to_struct")
  1165.         in
  1166.         app inst_to_struct (getSubSigs sign);
  1167.         let val str = INSTANCE {sign=sign,
  1168.                     subStrs=actual_subStrs,
  1169.                                         subFcts=fct_array,
  1170.                     types=actual_types,
  1171.                     path=path,
  1172.                     origin=get_origin instance}
  1173.         in
  1174.             final_struct := SOME str;
  1175.             str
  1176.         end
  1177.         end)
  1178.   | instance_to_structure _ ERRORinstance = ERROR_STR
  1179.   | instance_to_structure _ _ = 
  1180.       impossible "instantiate:instance_to_structure"
  1181.     
  1182.  
  1183. fun instantiate (sign,path,scope,error_fn) =
  1184.       let val ctx = (path,scope,error_fn)
  1185.           val result = instantiate_raw NONE ctx sign
  1186.       in
  1187.       visit_functor (Stamps.isBound scope) ctx result result; 
  1188.       result
  1189.       end 
  1190.  
  1191. and instantiate_raw argOption
  1192.             (ctx as (path, scope, error_fn))
  1193.             sign : Structure =
  1194.       let val _ = error_found := false
  1195.       val makeStamp = newStamp scope
  1196.       fun err sev msg = (error_found := true; error_fn sev msg)
  1197.       val instance_graph = 
  1198.         sig_to_instance(sign,path,makeStamp,err,argOption)
  1199.       val result = instance_to_structure (path,makeStamp) (instance_graph)
  1200.       in
  1201.       EqTypes.eqAnalyze(result,Stamps.isBound scope,err);
  1202.       result
  1203.       end
  1204.  
  1205. and visit_functor inParent ctx parent 
  1206.         (str as INSTANCE{sign=SIG{env,kind,...}, subFcts,subStrs,...}) =
  1207.       let val parent' = 
  1208.         case !kind 
  1209.         of TOP _ => str
  1210.          | _ => parent
  1211.       in
  1212.       Env.app
  1213.     (fn (name,STRbind(STRvar{binding=STR_FORMAL{pos,...},...})) => 
  1214.                if name=name_P then () 
  1215.            else visit_functor inParent ctx parent' (subStrs sub pos)
  1216.       | (name,FCTbind(FCTvar{binding=FCT_FORMAL{pos,spec},...})) =>
  1217.            update(subFcts,pos,instantiate_functor inParent ctx parent' spec)
  1218.       | (name,bind) => ())
  1219.     (!env)
  1220.       end
  1221.   | visit_functor _ _ _ str = ()
  1222.  
  1223. and instantiate_partial inParent argOption name ctx parent argument =
  1224.       let val arg_x = externalize_sharing name parent argument
  1225.       val arg_str = instantiate_raw argOption ctx arg_x
  1226.       in
  1227.       update_structure name parent arg_str;
  1228.       visit_functor inParent ctx arg_str arg_str;
  1229.       arg_str
  1230.       end
  1231. and instantiate_arg inParent paramName ctx = 
  1232.     instantiate_partial inParent (SOME paramName) name_P ctx
  1233. and instantiate_argument paramName (ctx as (_,scope,_)) =
  1234.       instantiate_arg (Stamps.isBound scope) paramName ctx
  1235. and instantiate_functor inParent ctx parent ERROR_FSIG = ERROR_FCT
  1236.   | instantiate_functor inParent ctx parent FULL_FSIG = 
  1237.       impossible "instantiate: instantiate_functor called on FULL_FSIG"
  1238.   | instantiate_functor inParent (ctx as (path, scope, error_fn))
  1239.             parent (FSIG{paramName,argument,body,...}) =
  1240.       let val argStampgen = Stamps.newBoundScope ()
  1241.           val bodyStampgen = Stamps.newBoundScope ()
  1242.           val inBody = Stamps.isBound bodyStampgen
  1243.       fun inArg s = inParent s orelse Stamps.isBound argStampgen s
  1244.           fun newInParent s = inBody s orelse inArg s
  1245.       val makeStamp = newStamp scope
  1246.           val arg_str = 
  1247.         instantiate_arg inParent 
  1248.                      paramName ([],argStampgen,error_fn)
  1249.                      parent argument
  1250.           val body_str =
  1251.                 instantiate_partial newInParent
  1252.           NONE name_A (path,bodyStampgen,error_fn) arg_str body
  1253.           val body_abs = 
  1254.             AbstractFct.abstractBody (body_str,arg_str,inBody,inArg)
  1255.       in 
  1256.       FCT{stamp=makeStamp(),paramName=paramName,parent=parent,
  1257.           argument=argument,body=body_abs}
  1258.       end
  1259. ;
  1260.  
  1261. end (* struct *)
  1262.